package com.lonepulse.icklebot.event; /* * #%L * IckleBot * %% * Copyright (C) 2013 Lonepulse * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import java.lang.reflect.Method; import java.util.Set; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import com.lonepulse.icklebot.annotation.event.Touch; import com.lonepulse.icklebot.event.resolver.EventCategory; import com.lonepulse.icklebot.util.ContextUtils; /** * <p>A concrete implementation of {@link EventLinker} which links methods * annotated with {@code @Click} to the specified {@link pView}s. * * @version 1.1.0 * <br><br> * @author <a href="mailto:lahiru@lonepulse.com">Lahiru Sahan Jayasinghe</a> */ class TouchEventLinker implements EventLinker { /** * {@inheritDoc} */ @Override public void link(EventLinker.Configuration config) { final Object listenerTemplate = config.getContext(); Set<Method> methods = config.getListenerTargets(EventCategory.TOUCH); for (final Method method : methods) { OnTouchListener onTouchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { try { if(!method.isAccessible()) method.setAccessible(true); Class<?>[] params = method.getParameterTypes(); Object[] args = new Object[params.length]; boolean argsPopulated = false; if(params.length < 3) { argsPopulated = true; for(int i = 0; i < params.length; i++) { if(View.class.isAssignableFrom(params[i])) { args[i] = v; } else if(MotionEvent.class.isAssignableFrom(params[i])) { args[i] = event; } else { argsPopulated = false; } } } if(argsPopulated) method.invoke(listenerTemplate, args); else method.invoke(listenerTemplate); } catch (Exception e) { StringBuilder builder = new StringBuilder() .append("Invocation of ") .append(method.getName()) .append(" at ") .append(listenerTemplate.getClass().getName()) .append(" failed for event OnTouch."); Log.e(getClass().getName(), builder.toString(), e); } return false; } }; try { int[] views = method.getAnnotation(Touch.class).value(); for (int id : views) { try { if(ContextUtils.isActivity(listenerTemplate)) { ContextUtils.asActivity(listenerTemplate) .findViewById(id).setOnTouchListener(onTouchListener); } else if(ContextUtils.isFragment(listenerTemplate)) { ContextUtils.asFragment(listenerTemplate) .getView().findViewById(id).setOnTouchListener(onTouchListener); } else if(ContextUtils.isSupportFragment(listenerTemplate)) { ContextUtils.asSupportFragment(listenerTemplate) .getView().findViewById(id).setOnTouchListener(onTouchListener); } } catch (Exception e) { StringBuilder builder = new StringBuilder() .append("Touch listener linking failed on method ") .append(method.getName()) .append(" at ") .append(listenerTemplate.getClass().getName()) .append(" for view with ID ") .append(ContextUtils.isActivity(listenerTemplate)? ContextUtils.asActivity(listenerTemplate).getResources().getResourceName(id) :ContextUtils.asFragment(listenerTemplate).getResources().getResourceName(id)) .append("."); Log.e(getClass().getName(), builder.toString(), e); } } } catch (Exception e) { StringBuilder builder = new StringBuilder() .append("Touch listener linking failed on method ") .append(method.getName()) .append(" at ") .append(listenerTemplate.getClass().getName()) .append("."); Log.e(getClass().getName(), builder.toString(), e); } } } }